﻿using LogLib;
using System;
using System.Collections.Concurrent;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using PhotoProcess.PxlSDK;
using ComLib.ComFun;

namespace PhotoProcess
{
    public class PhotoPreprocess
    {
        private PreprocessDirectory _dirConfig = new PreprocessDirectory();
   
        /// <summary>
        /// 等待处理事件
        /// </summary>
        protected ManualResetEvent _mresWaitHandler;

        /// <summary>
        /// 打印照片标准
        /// </summary>
        private const string FltFilePath = @"PxlSdk\epassport_PhotoPrint.flt";

        private string _error = "";
      
        public string ErrorMessage
        {
            get { return _error; }
        }

        private bool _bInited = false;
        public bool Inited
        {
            get { return _bInited; }
            set { _bInited = value; }
        }

        public PhotoPreprocess()
        {
            LoadConfig();
        }

        private void LoadConfig()
        {          
            _dirConfig.Load();
            if (!Directory.Exists(_dirConfig.RootDir))
            {
                Directory.CreateDirectory(_dirConfig.RootDir);
            }
        }

        public bool Init()
        {
            int ret = PxlDetect.FGDetectInitSDK();
            if (ret != 0)
            {
                if (ret == (int)PxlDetectPINVOKE.ErrCode._FGE_LICENSE_MISMATCH)
                {
                    _error = "没插白色加密狗.";
                    Log.WriteAsync(_error);
                    return false;
                }
                else
                {
                    _error = "PXL类库初始化失败: " + ret.ToString();
                    Log.WriteAsync(_error);
                    return false;
                }
            }
            Log.WriteAsync("PXL类库初始化成功.");
            _bInited = true;
            return true;
        }

        public bool Exit()
        {
            if (!_bInited)
            {
                return true;
            }
            int ret = PxlDetect.FGDetectExitSDK(); //释放像素dll
            if (ret != 0)
            {
                if (ret == (int)PxlDetectPINVOKE.ErrCode._FGE_LICENSE_MISMATCH)
                {
                    _error = "没插狗.";
                    Log.WriteAsync(_error);
                    return false;
                }
                else
                {
                    Log.WriteAsync("PXL类库卸载失败.");
                    return false;
                }
            }
            _bInited = false;
            Log.WriteAsync("PXL类库卸载成功.");
            return true;
        }

        public bool CreatPxlHandler(out IntPtr pxlHandle)
        {
            pxlHandle = IntPtr.Zero;
            // 创建算法识别句柄         
            int nRes = PxlDetect.FGDetectCreateHandleEmpty(ref pxlHandle);
            if (nRes != 0)
            {
                pxlHandle = IntPtr.Zero;
                _error = "创建算法识别句柄失败";
                Log.WriteAsync(_error);
                return false;
            }

            //加载特征文件
            nRes = PxlDetect.FGDetectLoadStdDataFromFile(pxlHandle, FltFilePath);
            if (nRes != 0)
            {
                pxlHandle = IntPtr.Zero;
                _error = "加载特征文件失败";
                Log.WriteAsync(_error);
                return false;
            }
            Log.WriteAsync("PXL句柄已创建");
            return true;
        }

        private void ReleasePxlHandler(IntPtr pxlHandle)
        {
            PxlDetect.FGDetectReleaseHandle(ref pxlHandle);
            Log.WriteAsync("PXL句柄已经释放");
        }

        public bool Handle(string strFilePath, string photoName, out string destFile)
        {
            Bitmap source = null;
            byte[] buffer = null;
            bool bResult = false;
            IntPtr pxlHandle = IntPtr.Zero;
            destFile = string.Format("{0}\\{1}.bmp", _dirConfig.Printing, photoName);
            if (!CreatPxlHandler(out pxlHandle))
            {
                return false;
            }
            try
            {            
                //像素裁切
                buffer = IPCCom.ReadByteArray(strFilePath);
                _FGFacePoint facePoint = new _FGFacePoint();
                DateTime dtStart = DateTime.Now;
                uint optFlags = (uint)PxlDetectPINVOKE.AdjustParam._FG_DSDK_AUTOAD_CROP
                    | (uint)PxlDetectPINVOKE.AdjustParam._FG_DSDK_AUTOAD_CLBK;
                    //| (uint)PxlDetectPINVOKE.AdjustParam._FG_DSDK_AUTOAD_FACE
                    //| (uint)PxlDetectPINVOKE.AdjustParam._FG_DSDK_AUTOAD_HOTS
                    //| (uint)PxlDetectPINVOKE.AdjustParam._FG_DSDK_AUTOAD_FCRP;

                int ret = PxlDetect.FGDetectImageAutoAdjust(pxlHandle, buffer, buffer.Length, optFlags, ref facePoint);//裁切
                if (ret != 0)
                {
                    _error = string.Format("PXL对原图裁切失败,错误代码: {0}", ret);
                    Log.WriteAsync(_error);                 
                    return bResult;
                }
                Object vData = new Object();
                ret = PxlDetect.FGDetectGetUnCompressedImage(pxlHandle, ref vData);  //获取裁切图像
                if (ret != 0)
                {                 
                    Array.Clear((byte[])vData, 0, ((byte[])vData).Length);
                    vData = null;
                    _error = string.Format("获取调整图像失败, 错误代码: {0}", ret);
                    Log.WriteAsync(_error);
                    return bResult;
                }

                using (MemoryStream ms = new MemoryStream((byte[])vData))
                {
                    Bitmap img = new Bitmap(ms);
                    img.Save(destFile, ImageFormat.Bmp);
                    ms.Close();
                }
                Log.WriteAsync(strFilePath + "处理完成!");
                bResult = true;
                return bResult;
            }
            catch(Exception ex)
            {
                _error = ex.Message;
                Log.WriteException(ex.ToString());
                return false;
            }
            finally
            {
                if (buffer != null)
                {
                    Array.Clear(buffer, 0, buffer.Length);
                    buffer = null;
                }
                if(source != null)
                {
                     source.Dispose();
                     source = null;
                }
                ReleasePxlHandler(pxlHandle);
            }          
        }
    }
}
